<?php
// +----------------------------------------------------------------------
// | zhanshop-proxy / IndexEvnet.php    [ 2023/12/4 21:17 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2011~2023 zhangqiquan All rights reserved.
// +----------------------------------------------------------------------
// | Author: zhangqiquan <768617998@qq.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace app\api\admin;
use app\helper\ProxyAccountShareData;
use app\helper\ProxyDnsShareData;
use extend\bridgecli\BridgClient;
use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\WebSocket\Frame;
use zhanshop\App;
use zhanshop\Log;
use zhanshop\server\Event;
use zhanshop\util\ShareData;

class WebsocketEvent extends Event {

    public string $servName = 'admin';
    /**
     * 工作进程启动
     * @param \Swoole\Http\Server $server
     * @param int $workerId
     * @return void
     */
    public function onWorkerStart($server, $workerId) :void{
        parent::onWorkerStart($server, $workerId);

        if($workerId == $server->setting['worker_num']) {
            try {
                App::make(BridgClient::class, [$workerId]);
            }catch (\Throwable $e){
                Log::errorLog(5, $e->getMessage().PHP_EOL.'#@ '.$e->getFile().':'.$e->getLine().PHP_EOL.$e->getTraceAsString().PHP_EOL);
            }
        }
        //$this->proxyInit(); // 初始化代理信息
    }

    protected function proxyInit()
    {
        try {
            // 载入共享内存
            $accounts = App::database()->model("proxy_account")->select();
            foreach($accounts as $v){
                App::make(ProxyAccountShareData::class)->set($v['name'], [
                    'name' => $v['name'],
                    'pwd' => $v['password'],
                ]);
            }

            $accounts = App::database()->model("proxy_dns")->select();
            foreach($accounts as $v){
                App::make(ProxyDnsShareData::class)->set($v['domain'], [
                    'sock_type' => intval($v['sock_type']),
                    'protocol' => intval($v['protocol']),
                    'address' => $v['address'],
                ]);
            }

        }catch (\Throwable $e){
            Log::errorLog(5, $e->getMessage());
        }
    }
    /**
     * @param Request $request
     * @param Response $response
     * @return void
     */
    public function onRequest($request, $response) :void{
        if(!$this->onStatic($request, $response)){
            parent::onRequest($request, $response);
        }
    }

    /**
     * 首次请求
     * @param \Swoole\WebSocket\Server $server
     * @param Request $request
     * @param int $protocol
     * @param string $appName
     * @return void
     */
    public function onOpen($server, $request) :void{
        parent::onOpen($server, $request);
    }

    /**
     * 消息响应
     * @param \Swoole\WebSocket\Server $server
     * @param Frame $frame
     * @param int $protocol
     * @param string $appName
     * @return void
     */
    public function onMessage($server, $frame) :void{
        parent::onMessage($server, $frame);
    }

    /**
     * @param \Swoole\WebSocket\Server $server
     * @param int $fd
     * @param int $reactorId
     * @return void
     */
    public function onClose($server, $fd, $reactorId) :void{
        $sfd = (string)$fd;
        if(ShareData::exist($sfd)){
            ShareData::del($sfd);
        }
    }

    /**
     * 静态访问响应
     * @param \Swoole\Http\Response $request
     * @param \Swoole\Http\Response $response
     * @return bool
     */
    private function onStatic($request, $response){
        try{
            $uri = App::rootPath().'/public'.$request->server['request_uri'];
            if(file_exists($uri)){
                if(is_dir($uri)) $uri = rtrim($uri, '/').'/index.html';
                $lastModifiedTime = filemtime($uri);
                $response->header('Server', 'zhanshop');
                if(($request->header['if-modified-since'] ?? 0) == $lastModifiedTime){
                    $response->status(304);
                    $response->end();
                    return true;
                }
                $response->header('Last-Modified', strval($lastModifiedTime));
                $response->sendfile($uri);
                return true;
            }
        }catch (\Throwable $e){}

        return false;
    }

}